package top.ochiamalu.aioj.manager;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import top.ochiamalu.aioj.constant.JudgeResultConstants;
import top.ochiamalu.aioj.domain.bo.ExecuteMessage;
import top.ochiamalu.aioj.domain.entity.Answer;
import top.ochiamalu.aioj.domain.entity.TestCase;
import top.ochiamalu.aioj.factory.CodeExecutorFactory;
import top.ochiamalu.aioj.strategy.judge.CodeExecutor;

import javax.annotation.Resource;
import java.io.File;
import java.util.List;

/**
 * 判题管理类
 *
 * @author ochiamalu
 * @date 2025/06/20
 */
@Component
@Slf4j
public class JudgeManager {

    @Resource
    private CodeExecutorFactory codeExecutorFactory;

    /**
     * 编译并检查代码
     *
     * @param language      编程语言
     * @param code          代码内容
     * @param answer        答案对象
     * @param submissionId  提交ID
     * @return 代码文件和编译结果 (如果成功)
     */
    public File compileAndCheck(String language, String code, Answer answer, String submissionId) {
        if (StringUtils.isBlank(code)) {
            answer.setStatus(JudgeResultConstants.COMPILE_ERROR);
            answer.setTime(0);
            answer.setMemory(0);
            answer.setScore(0);
            answer.setCompilerOutput("代码不能为空");
            return null;
        }

        CodeExecutor executor = codeExecutorFactory.getExecutor(language);
        File userCodeFile = executor.saveCodeToFile(code);
        
        if (log.isInfoEnabled()) {
            log.info("save to path = {}", userCodeFile.getAbsolutePath());
        }

        ExecuteMessage compileMessage = executor.compileFile(userCodeFile);
        if (compileMessage.getExitValue() != 0) {
            executor.deleteFile(userCodeFile);
            answer.setStatus(JudgeResultConstants.COMPILE_ERROR);
            answer.setTime(0);
            answer.setMemory(0);
            answer.setScore(0);
            answer.setCompilerOutput(executor.handleErrorMessage(userCodeFile, compileMessage.getMessage()));
            return null;
        }
        
        return userCodeFile;
    }

    /**
     * 执行代码
     *
     * @param userCodeFile  用户代码文件
     * @param testCaseList  测试用例信息列表
     * @param language      编程语言
     * @return 执行消息列表
     */
    public List<ExecuteMessage> executeCode(File userCodeFile, List<TestCase> testCaseList, String language) {
        CodeExecutor executor = codeExecutorFactory.getExecutor(language);
        return executor.runFile(userCodeFile, testCaseList);
    }
    
    /**
     * 获取编译器名称
     *
     * @param language 语言
     * @return 编译器名称
     */
    public String getCompilerName(String language) {
        return codeExecutorFactory.getExecutor(language).getCompilerName();
    }
    
    /**
     * 计算最大分数
     */
    public int calculateMaxScore(List<TestCase> testCaseList) {
        return testCaseList.stream()
                .mapToInt(TestCase::getScore)
                .sum();
    }

    /**
     * 验证测试用例
     */
    public boolean validateTestCases(List<TestCase> testCaseList, Answer answer, String submissionId) {
        if (testCaseList.isEmpty()) {
            answer.setStatus(JudgeResultConstants.INTERNAL_ERROR);
            answer.setTime(0);
            answer.setMemory(0);
            answer.setScore(0);
            answer.setErrorMessage("Need at least one TestCase.");
            return false;
        }
        return true;
    }
    
    /**
     * 删除代码文件
     */
    public void deleteCodeFile(File userCodeFile, String language) {
        CodeExecutor executor = codeExecutorFactory.getExecutor(language);
        executor.deleteFile(userCodeFile);
    }
} 